package com.atguigu.gmall.seckill.task;

import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.seckill.mapper.SeckillMapper;
import com.atguigu.gmall.seckill.util.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Set;


@Component
public class SeckillTask {
    @Autowired
    private SeckillMapper seckillMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 秒杀商品存入缓存的定时任务
     */
    @Scheduled(cron = "0/15 * * * * *")
    public void seckillIntoRedisTask(){
        //计算时间：5个时间段
        List<Date> dateMenus = DateUtil.getDateMenus();
        for (Date dateMenu : dateMenus) {

            //从数据库查询出对应时间段的商品数据2021-7-14 20：00
            String startTime = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYY_MM_DDHHMM);
            //结算时间段的截止时间：2021-7-14 16:00
            Date date = DateUtil.addDateHour(dateMenu, 2);
            String endTime = DateUtil.data2str(date, DateUtil.PATTERN_YYYY_MM_DDHHMM);
            LambdaQueryWrapper<SeckillGoods> wrapper = new LambdaQueryWrapper<>();
            //审核状态必须是通过的
            wrapper.eq(SeckillGoods::getStatus,"1");
            //剩余库存大于0
            wrapper.gt(SeckillGoods::getStockCount,0);
            //时间段
            wrapper.ge(SeckillGoods::getStartTime,startTime);
            wrapper.eq(SeckillGoods::getEndTime,endTime);
            //redis
            String key = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYYMMDDHH);
            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + key).keys();
            if (keys != null && keys.size() > 0){
                wrapper.notIn(SeckillGoods::getId, keys);
            }
            //查询数据库的数据
            List<SeckillGoods> seckillGoods = seckillMapper.selectList(wrapper);
            //存入Redis: SeckillGoods_2021071420
            for (SeckillGoods seckillGood : seckillGoods) {

                redisTemplate.boundHashOps("SeckillGoods_"+key).put(seckillGood.getId(),seckillGood);
                //获取商品的库存数量1000个
                Integer stockCount = seckillGood.getStockCount();
                //构建一个数量长度的数组
                String[] ids = getSeckillGoodsQueue(seckillGood.getId(),stockCount);
                //将数组中的每个元素都存储到redis的list队列中去
                redisTemplate.boundListOps("seckillGoodsQueue_" + seckillGood.getId()).leftPushAll(ids);
                //库存进行记录
                redisTemplate.boundHashOps("SeckillGoodsStockNum").increment(seckillGood.getId(),stockCount);
            }
        }
    }

    /**
     * 构建商品库存个数长度的数组
     * @param goodsId
     * @param stockCount
     * @return
     */
    private String[] getSeckillGoodsQueue(String goodsId, Integer stockCount) {
        //构建一个库存长度的数组
        String[] ids = new String[stockCount];
        //元素填充
        for (int i = 0; i < stockCount; i++) {
            ids[i] = goodsId;
        }
        //返回数据
        return ids;
    }
}
